package com.suray.wcs.service.system.service.impl;

import com.suray.basic.wcs.plc.enums.Location;
import com.suray.basic.wcs.plc.enums.Network;
import com.suray.basic.wcs.plc.pojo.oper.lifter.LifterOper;
import com.suray.basic.wcs.plc.pojo.oper.lifter.TwoDirectionRgvLifterOper;
import com.suray.basic.wcs.plc.pojo.oper.lifter.ForkLifterOper;
import com.suray.basic.wcs.utils.Coord;
import com.suray.commin.core.utils.SpringContextHolder;
import com.suray.basic.wcs.plc.service.impl.LifterCodeDBServiceImpl;
import com.suray.wcs.service.core.util.LockNodeManager;
import com.suray.wcs.service.enums.CodeType;
import com.suray.wcs.service.plc.LifterEvent;
import com.suray.wcs.service.pojo.HandHoist;
import com.suray.wcs.service.pojo.HoistHandleBean;
import com.suray.wcs.service.pojo.Rgv;
import com.suray.wcs.service.system.entity.TaskDB;
import com.suray.wcs.service.system.service.HoisterOperService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


@Service
public class HoisterOperServiceImp implements HoisterOperService {
    private CodeDBServiceImpl codeDBService = SpringContextHolder.getBean(CodeDBServiceImpl.class);
    private LifterCodeDBServiceImpl lifterCodeDBService = SpringContextHolder.getBean(LifterCodeDBServiceImpl.class);

    /**
     * 小车到位
     *
     * @param lifterOper 操作对象
     */
    @Override
    public void setHoistShuttleArrived(LifterOper lifterOper) throws IOException {
        lifterOper.setHoistShuttleArrived();
    }

    /**
     * 清除当前提升机任务
     *
     * @param lifterOper
     */
    @Override
    public void hoistTaskClear(LifterOper lifterOper) throws IOException {
        lifterOper.setHoistTaskClear();
    }

    /**
     * 获取提升机显示信息
     *
     * @param lifterOper 提升机操作对象
     * @return
     */
    @Override
    public HandHoist getHoistInfo(LifterOper lifterOper) {

        HandHoist handHoist = new HandHoist();
        handHoist.setHoistName(lifterOper.getDeviceName());
        for (int floor = 1; floor < 11; floor++) {
            handHoist.getLoInfo().add(new HoistHandleBean(floor, "左", lifterOper.isFacilityProblem(floor, Location.LEFT) ? "故障" : "未故障", lifterOper.isPalletExisted(floor, Location.LEFT) ? "有货" : "无货", lifterOper.isFacilityExisted(floor, Location.LEFT) ? "运行" : "未运行"));
            handHoist.getLoInfo().add(new HoistHandleBean(floor, "右", lifterOper.isFacilityProblem(floor, Location.RIGHT) ? "故障" : "未故障", lifterOper.isPalletExisted(floor, Location.RIGHT) ? "有货" : "无货", lifterOper.isFacilityExisted(floor, Location.RIGHT) ? "运行" : "未运行"));
        }
        handHoist.setCurFloor(lifterOper.getHoistCurrentLayer());
        handHoist.setLocalRemote(lifterOper.isRemoteMode() ? "远程" : "本地");
        handHoist.setCargoIn(lifterOper.isHoistGoodArrived() ? "到位" : "未到位");
        handHoist.setCheckNo(lifterOper.getCheckNo());
        handHoist.setControllerMode(lifterOper.isAutoMode() ? "自动" : "手动");
        handHoist.setEngineState(lifterOper.isHoistConveyInsideStop() ? "内部链条机未运行" : "内部链条机运行中");
        List<String> errorList = new ArrayList<>();
        int lifterErrorCode = lifterOper.getLifterErrorCode();
        String message = codeDBService.getCodeDescByFault(lifterErrorCode, CodeType.LIFTER_ERROR_CODE);

        putErrorList(errorList,message);


        handHoist.setErrorState(errorList);

        handHoist.setCompleteTaskNo(lifterOper.getHoistFinalTaskNo());

        handHoist.setHaveCar(lifterOper.isHaveShuttle() ? "提升机内有小车" : "提升机内无小车");

        handHoist.setHaveCargo(lifterOper.isHaveCargo() ? "有货" : "无货");

        handHoist.setHoistLay(
                lifterOper.getHoistCurrentLayer() == 0 ? "提升机在非平层" : "提升机在" + lifterOper.getHoistCurrentLayer() + "层");

        handHoist.setCurFloor(lifterOper.getHoistCurrentLayer());
        handHoist.setInState(lifterOper.isArrived() ? "到位" : "未到位");

        handHoist.setReadyState(lifterOper.isReady() ? "就绪" : "未就绪");

        handHoist.setRunningState(lifterOper.isRuning() ? "提升机运行中" : "提升机未运行");

        handHoist.setScram(lifterOper.isEmergencyStop() ? "急停" : "未急停");

        handHoist.setTaskNo(lifterOper.getHoistCurrentTaskNo());

        handHoist.setLockStatus(lifterOper.lockState() ? "已锁定" : "未锁定");
        if (lifterOper instanceof TwoDirectionRgvLifterOper) {
            TwoDirectionRgvLifterOper twoDirectionRgvLifterOper = (TwoDirectionRgvLifterOper) lifterOper;
            if (twoDirectionRgvLifterOper.isTwoDirectionRgvLayerArrived()) {
                handHoist.setHoistStatueLayer("二向车层");
            } else if (twoDirectionRgvLifterOper.isArrived()) {
                handHoist.setHoistStatueLayer("四向车层");
            }
            handHoist.setTwoDirectionRgv(twoDirectionRgvLifterOper.isHasTwoDirectionRgv() ? "有" : "无");
            handHoist.setHasRgv(twoDirectionRgvLifterOper.isHaveShuttle() ? "有" : "无");
        }
        Set<Coord> hoistSet = new HashSet<>();
        for (int i = 1; i <= 15; i++) {
            hoistSet.add(new Coord(lifterOper.getCoord().getX(), lifterOper.getCoord().getY(), i));
        }
        if (LockNodeManager.isLocked(hoistSet) == null) {
            handHoist.setWcsLockStatus("未锁定");
        } else {
            String lockBy;
            Object obj = LockNodeManager.isLocked(hoistSet);
            if (obj == null) {
                lockBy = "暂无";
            } else if (obj instanceof Rgv) {
                lockBy = ((Rgv) obj).getRgvName();
            } else if (obj instanceof TaskDB) {
                lockBy = ((TaskDB) obj).getTaskId().toString();
            } else {
                lockBy = obj.toString();
            }
            handHoist.setWcsLockStatus("已锁定" + "/" + lockBy);
        }

        return handHoist;

    }

    /**
     * 获取提升机显示信息
     *
     * @param forkLifterOper 提升机操作对象
     * @return
     */
    @Override
    public HandHoist getForkHoisterInfo(ForkLifterOper forkLifterOper) {
        HandHoist handHoist = new HandHoist();
        handHoist.setLifterFloor(forkLifterOper.getGridzMax());
        handHoist.setPalletUpDis(forkLifterOper.getPalletUpDis());
        handHoist.setPalletDownDis(forkLifterOper.getPalletDownDis());
        handHoist.setCarInLifterDis(forkLifterOper.getCarInLifterDis());
        handHoist.setLeftLocationDis(forkLifterOper.getLeftLocationDis());
        handHoist.setRightLocationDis(forkLifterOper.getRightLocationDis());
        handHoist.setTwoCarLayerDis(forkLifterOper.getTwoCarLayerDis());
        handHoist.setFourCarLayerDis(forkLifterOper.getFourCarLayerDis());
        handHoist.setTaskProcess(forkLifterOper.getTaskProcess() == null ? "暂无" : forkLifterOper.getTaskProcess().toString());
        handHoist.setWcsTaskId(forkLifterOper.getTaskId());
        if (forkLifterOper.getPlc().getPlcStatus() == Network.OFF_LINE) {
            handHoist.setReadyState("离线");
            return handHoist;
        }
        //是否就绪
        handHoist.setReadyState(forkLifterOper.isReady() ? "就绪" : "未就绪");
        //提升机名称
        handHoist.setHoistName(forkLifterOper.getDeviceName());
        //货位是否到位
        handHoist.setCargoIn(forkLifterOper.isArrived() ? "到位" : "未到位");
        //生命
        handHoist.setCheckNo(forkLifterOper.getCheckNo());//生命
        //提升机内是否有四向车
        handHoist.setHaveCar(forkLifterOper.isFourCarLeftSig() ? "提升机内有四向车" : "提升机内无四向车");
        //已完成任务号
        handHoist.setCompleteTaskNo(forkLifterOper.getHoistFinalTaskNo());
        //提升机内是否有两向车
        handHoist.setHaveCar(forkLifterOper.isTwoCarLeftSig() ? "提升机内有两向车" : "提升机内无两向车");
        //是否有货
        handHoist.setHaveCargo(forkLifterOper.isHaveCargo() ? "有货" : "无货");
        //提升机当前层
        handHoist.setHoistLay(forkLifterOper.getHoistCurrentLayer() == 0 ? "提升机在非平层" : "提升机在" + forkLifterOper.getHoistCurrentLayer()
                + "层" + forkLifterOper.getHoistLayerType().toString());
        //是否到位
        handHoist.setInState(forkLifterOper.isArrived() ? "到位" : "未到位");
        //提升机是否运行
        handHoist.setRunningState(forkLifterOper.isRuning() ? "提升机运行中" : "提升机未运行");
        //提升机当前任务
        handHoist.setTaskNo(forkLifterOper.getTaskingId());
        handHoist.setTwoDirectionRgv(forkLifterOper.hasTwoCarInLifter() ? "有" : "无");
        handHoist.setCurFloor(forkLifterOper.getHoistCurrentLayer());
        handHoist.setLifterLayerType(forkLifterOper.getHoistLayerType() == null ? "暂无" : forkLifterOper.getHoistLayerType().toString());
        Integer gridzMax = forkLifterOper.getGridzMax() + forkLifterOper.getGridzRelative() - 1;
        Integer guidzRelative = forkLifterOper.getGridzRelative();
        Set<Coord> hoistSet = new HashSet<>();
        for (int i = guidzRelative; i <= gridzMax; i++) {
            hoistSet.add(new Coord(forkLifterOper.getCoord().getX(), forkLifterOper.getCoord().getY(), i));
        }
        if (LockNodeManager.isLocked(hoistSet) == null) {
            handHoist.setWcsLockStatus("未锁定");
        } else {
            String lockBy;
            Object obj = LockNodeManager.isLocked(hoistSet);
            if (obj == null) {
                lockBy = "暂无";
            } else if (obj instanceof Rgv) {
                lockBy = ((Rgv) obj).getRgvName();
            } else if (obj instanceof TaskDB) {
                lockBy = ((TaskDB) obj).getTaskId().toString();
            } else {
                lockBy = obj.toString();
            }
            handHoist.setWcsLockStatus("已锁定" + "/" + lockBy);
        }
        handHoist.setDebugMode(forkLifterOper.isDebugMode() ? "调试" : "自动");
        handHoist.setLockStatus(forkLifterOper.lockState() ? "锁定" : "未锁定");
        handHoist.setTaskDes(forkLifterOper.getTaskDes());
        handHoist.setTwoCarDriving(forkLifterOper.isTwoCarDriving() ? "行驶中" : "未行使");
        //托盘状态
        handHoist.setPalletStatus(forkLifterOper.isTwoCarUpOk() ? "顶升" :
                forkLifterOper.isTwoCarDownOk() ? "下降" : "异常");
        //提升机位移
        handHoist.setCurLifterDis(forkLifterOper.getLifterDis());
        handHoist.setCurCarDis(forkLifterOper.getTwoCarDis());
        handHoist.setCurCarPalletDis(forkLifterOper.getTwoCarPalletDis());
        handHoist.setCurCarGroundCode(forkLifterOper.getTwoCarGroundCode() + "");
        handHoist.setCurCarLocation(forkLifterOper.getTwoCarLocal() == 1 ? "提升机左"
                : forkLifterOper.getTwoCarLocal() == 2 ? "提升机右"
                        : forkLifterOper.getTwoCarLocal() == 3 ? "提升机内" : "异常");
        //平台上限位开关
        handHoist.setUpLimit(forkLifterOper.overUpLimit() ? "异常" : "正常");
        //平台下限位开关
        handHoist.setDownLimit(forkLifterOper.overDownLimit() ? "异常" : "正常");
        if (forkLifterOper.isZhouEnable1() && forkLifterOper.isZhouEnable2() && forkLifterOper.isZhouEnable3() && forkLifterOper.isZhouEnable4()) {
            handHoist.setLifterEnable("使能");
        } else {
            handHoist.setLifterEnable("未使能");
        }
        // 设置提升机轴使能信息和故障信息
        setLifterZhouInfo(handHoist, forkLifterOper);

        if (forkLifterOper.isTwoCarDriverEnable() && forkLifterOper.isTwoCarPalletEnable()) {
            handHoist.setCarEnable("使能");
        } else {
            handHoist.setCarEnable("未使能");
        }
        // 设置提升机光电信号
        setLifterLightSignal(handHoist, forkLifterOper);
        //行驶接触器
        handHoist.setDriveContact(forkLifterOper.isDriveContact() ? "正常" : "异常");
        //升降接触器
        handHoist.setUpDownContact(forkLifterOper.isUpDownContact() ? "正常" : "异常");
        //5V电源
        handHoist.setPower5(forkLifterOper.isPower5() ? "正常" : "异常");
        //行驶刹车
        handHoist.setDriveBrake(forkLifterOper.isDriveBrake() ? "正常" : "异常");
        //电器盒加热
        handHoist.setPlcHeat(forkLifterOper.isPlcHeat() ? "正常" : "异常");
        // 两向车托盘下降到位
        handHoist.setTwoCarDownOk(forkLifterOper.isTwoCarDownOk());
        handHoist.setTwoCarUpOk(forkLifterOper.isTwoCarUpOk());
        handHoist.setCanDoTask(forkLifterOper.isReady() ? "可接收" : "不可接收");
        int errorCode = forkLifterOper.getErrorCode();
        if (errorCode > 0) {
            String errorMessage = lifterCodeDBService.getCodeDescByError(forkLifterOper.getErrorCode());
            handHoist.setErrorCodeInfo(errorMessage);
        }

        handHoist.setLife(forkLifterOper.getCheckNo());
        handHoist.setTaskingId(forkLifterOper.getTaskingId());
        handHoist.setTaskingCmdNo(forkLifterOper.getTaskingCmdNo());
        handHoist.setFinishCmdNo(forkLifterOper.getFinishCmdNo());
        handHoist.setFinishTaskId(forkLifterOper.getHoistFinalTaskNo());
        handHoist.setCurrentLayer(forkLifterOper.getHoistCurrentLayer());
        handHoist.setWarnCode(forkLifterOper.getWarnCode());
        handHoist.setArrived((forkLifterOper.isArrived() && forkLifterOper.isCarArrived()) ? "到位" : "未到位");
        handHoist.setLifterArrived(forkLifterOper.isArrived() ? "到位" : "未到位");
        handHoist.setCarArrived(forkLifterOper.isCarArrived() ? "到位" : "未到位");
        return handHoist;

    }

    /**
     * 设置提升机轴使能信息和故障信息
     *
     * @param handHoist   推送到前端的类
     * @param forkLifterOper 提升机基础类
     */
    private void setLifterZhouInfo(HandHoist handHoist, ForkLifterOper forkLifterOper) {
        //1轴报错状态
        handHoist.setZhouError1(forkLifterOper.isZhouError1() ? "故障" : "无故障");
        //2轴报错状态
        handHoist.setZhouError2(forkLifterOper.isZhouError2() ? "故障" : "无故障");
        //3轴报错状态
        handHoist.setZhouError3(forkLifterOper.isZhouError3() ? "故障" : "无故障");
        //4轴报错状态
        handHoist.setZhouError4(forkLifterOper.isZhouError4() ? "故障" : "无故障");
        //1轴使能状态
        handHoist.setZhouEnable1(forkLifterOper.isZhouEnable1() ? "使能" : "未使能");
        //2轴使能状态
        handHoist.setZhouEnable2(forkLifterOper.isZhouEnable2() ? "使能" : "未使能");
        //3轴使能状态
        handHoist.setZhouEnable3(forkLifterOper.isZhouEnable3() ? "使能" : "未使能");
        //4轴使能状态
        handHoist.setZhouEnable4(forkLifterOper.isZhouEnable4() ? "使能" : "未使能");
        //两向车行驶轴使能状态
        handHoist.setTwoCarDriveEnable(forkLifterOper.isTwoCarDriverEnable() ? "使能" : "未使能");
        //两向车行驶轴报错状态
        handHoist.setTwoCarDriveError(forkLifterOper.isTwoCarDriveError() ? "故障" : "正常");
        //两向车升降轴使能状态
        handHoist.setTwoCarPalletEnable(forkLifterOper.isTwoCarPalletEnable() ? "使能" : "未使能");
        //两向车升降轴报错状态
        handHoist.setTwoCarPalletError(forkLifterOper.isTwoCarPalletError() ? "故障" : "正常");
    }


    /**
     * 设置提升机光电信号
     *
     * @param handHoist
     * @param forkLifterOper
     */
    private void setLifterLightSignal(HandHoist handHoist, ForkLifterOper forkLifterOper) {
        //1方向检测四向车光电信号
        handHoist.setDirection1CarSig(forkLifterOper.isDirection1CarSig() ? "有信号" : "无信号");
        //3方向检测四向车光电信号
        handHoist.setDirection3CarSig(forkLifterOper.isDirection3CarSig() ? "有信号" : "无信号");
        //1方向检测托盘光电信号
        handHoist.setDirection1PalletSig(forkLifterOper.isDirection1PalletSig() ? "有信号" : "无信号");
        //3方向检测托盘光电信号
        handHoist.setDirection3PalletSig(forkLifterOper.isDirection3PalletSig() ? "有信号" : "无信号");
        //4#1方向托盘光电
        handHoist.setDir1PalletSig(forkLifterOper.isDir1PalletSig() ? "有信号" : "无信号");
        //4#3方向托盘光电
        handHoist.setDir3PalletSig(forkLifterOper.isDir3PalletSig() ? "有信号" : "无信号");

        handHoist.setDir2PalletSig(forkLifterOper.isDir2PalletSig() ? "有信号" : "无信号");
        //凸轮光电信号1
        handHoist.setCamSig1(forkLifterOper.isCamSig1() ? "有信号" : "无信号");
        //凸轮光电信号2
        handHoist.setCamSig2(forkLifterOper.isCamSig2() ? "有信号" : "无信号");
        //四向车平台左光电
        handHoist.setFourCarLeftSig(forkLifterOper.isFourCarLeftSig() ? "有信号" : "无信号");
        //四向车平台右光电
        handHoist.setFourCarRightSig(forkLifterOper.isDir1PalletSig() ? "有信号" : "无信号");
        //平台检测四向车光电
        handHoist.setHasFourCarSig(forkLifterOper.isHaveShuttle() ? "有信号" : "无信号");
        //平台检测两向车光电
        handHoist.setHasTwoCarSig(forkLifterOper.hasTwoCarInLifter() ? "有信号" : "无信号");
        //两向车平台左光电
        handHoist.setTwoCarLeftSig(forkLifterOper.isTwoCarLeftSig() ? "有信号" : "无信号");
        //两向车平台右光电
        handHoist.setTwoCarRightSig(forkLifterOper.isTwoCarRightSig() ? "有信号" : "无信号");
        //凸轮限位开关信号
        handHoist.setCamLimit(forkLifterOper.isCamLimit() ? "有信号" : "无信号");
    }


    private void putErrorList(List<String> errorList, String errorMessage) {
        if (StringUtils.isEmpty(errorMessage)) {
            return;
        }
        errorList.add(errorMessage);
    }

    /**
     * 小车驶离
     *
     * @param deviceOper
     */
    @Override
    public void hoistShuttleOuted(LifterOper deviceOper) throws IOException {
        deviceOper.setHoistShuttleOuted();
    }

    /**
     * 清除提升机故障
     *
     * @param deviceOper
     */
    @Override
    public void hoistCurrentErrorClear(LifterOper deviceOper) throws IOException {
        // TODO Auto-generated method stub
        deviceOper.setHoistCurrentErrorClear();
    }

    /**
     * 上锁
     *
     * @param password
     * @param deviceOper
     * @return true 成功 false失败
     */
    @Override
    public boolean hoistLock(Integer password, LifterOper deviceOper) throws IOException {
        deviceOper.lockHoist(password);
//        deviceOper.writePassword(password);
        return !deviceOper.lockProblem();

    }

    /**
     * 解锁
     *
     * @param password
     * @param deviceOper
     * @return false 失败 true 成功
     */
    @Override
    public boolean hoistUnlock(Integer password, LifterOper deviceOper) throws IOException {
//        deviceOper.writePassword(password);
        deviceOper.unlockHoist(password);
        return !deviceOper.unlockProblem();
    }

    /**
     * 清除完成任务编号
     *
     * @param lifterOper
     */
    @Override
    public void hoistFinalTaskNoClear(LifterOper lifterOper) throws IOException {
        lifterOper.setHoistFinalTaskNoClear();
        LifterEvent.liftWord.remove(lifterOper.getLockLocation().toString());
    }

}
